// 1.引入库
import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import { getTimeStamp } from '@/utils/auth'
import router from '@/router'

// 封装校验是否超时的函数
const checkTimeout = () => {
  // 1.设定超时间隔
  const timeout = 1000 * 60 * 60 * 2
  // 2.获取之前的记录
  const loginTime = getTimeStamp()
  // 3.获取当前时间
  const now = new Date()
  const nowTime = now.getTime()
  // 4.当前时间减去之前的记录时间,如果>时间间隔就是超时了
  return nowTime - loginTime > timeout
}

// 2.创建实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 前提，有token
    if (store.getters.token) {
      // 主动介入token是否超时
      const isTimeout = checkTimeout()
      if (isTimeout) {
        // 如果已经超时，想报错一样，拒绝掉当前的请求
        // 还需要 清理 用户数据(其实就是执行登出)
        store.dispatch('user/logout')
        // 跳转到登录页
        router.push('/login')
        return Promise.reject(new Error('已超时，请重新登录'))
      }
      // 统一添加token
      // 我们这个项目使用的是 Brarer JWT token 标准
      // 固定标准写法为 'BRARER ***'
      config.headers.Authorization = `Bearer ${store.getters.token}`
    }

    // 不管怎么样都要放行
    return config
  },
  // 失败请求回调（暂时没有失败的情况，先写一个占位）
  err => {
    console.log(err)
    return Promise.reject('请求失败')
  }
)

// 响应拦截器
// 响应拦截器可以接受两个参数
// 第一个是网络层面成功的回调
// 第二个是网络仓面失败的回调
service.interceptors.response.use(
  res => {
    // 这是网络层面的成功
    // console.log('网络层面的成功')
    // console.log(res)
    const { success, message, data } = res.data
    if (success) {
      // 返回数据
      return data
    } else {
      // 数据层面的失败
      // 1. 提示错误
      Message.error(message)
      // 2. 拒绝当前的 promise 继续执行
      return Promise.reject(new Error(message))
    }
  },
  err => {
    // 这里报错的可能性非常多，断网，路径错误，服务器奔溃啊
    // 其中有一种就是后端认为我们token失效
    // 我们要对这种错误进行判断，特俗处理
    // 我们和后端约定，如果报错的同事给出的代码是 10002 就是超时
    if (err.response && err.response.data && err.response.data.code === 10002) {
      // 还需要 清理 用户数据(其实就是执行登出)
      store.dispatch('user/logout')
      // 跳转到登录页
      router.push('/login')
    }
    console.log(err)
    // 网络层面的失败
    // 1. 提示错误
    Message.error(err.message || '系统繁忙, 请稍后再试')
    // 2. 拒绝当前的 promise 请求继续执行
    return Promise.reject(new Error('系统繁忙, 请稍后再试'))
  }
)

export default service
